import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
  Mesh,
  BoxBufferGeometry,
  MeshBasicMaterial,
  TextureLoader,
  Color,
  PlaneBufferGeometry,
  DoubleSide,
  CanvasTexture,
} from "three";

let camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer;
let control: OrbitControls;

init();
animate();

function init() {
  camera = new PerspectiveCamera(
    70,
    window.innerWidth / window.innerHeight,
    1,
    10000
  );
  camera.position.set(0, 75, 100);

  scene = new Scene();
  scene.background = new Color("#003300");

  let geometry = new PlaneBufferGeometry(100, 100);
  let texture = new CanvasTexture(generateTexture());

  for (let i = 0; i < 15; i++) {
    let material = new MeshBasicMaterial({
      color: new Color().setHSL(0.3, 0.75, (i / 15) * 0.4 + 0.1),
      map: texture,
      depthTest: false,
      depthWrite: false,
      transparent: true,
    });
    let mesh = new Mesh(geometry, material);
    mesh.position.y = i * 0.25;
    mesh.rotateX(-Math.PI / 2);
    scene.add(mesh);
  }
  // scene.children.reverse();

  renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  control = new OrbitControls(camera, renderer.domElement);
  document.body.appendChild(renderer.domElement);
  // renderer.render(scene, camera);
}

function generateTexture() {
  const canvas = document.createElement("canvas");
  canvas.width = 512;
  canvas.height = 512;

  const context = canvas.getContext("2d");

  for (let i = 0; i < 20000; i++) {
    context.fillStyle = "hsl(0,0%," + (Math.random() * 50 + 50) + "%)";
    context.beginPath();
    context.arc(
      Math.random() * canvas.width,
      Math.random() * canvas.height,
      Math.random() + 0.15,
      0,
      Math.PI * 2,
      true
    );
    context.fill();
  }

  context.globalAlpha = 0.075;
  context.globalCompositeOperation = "lighter";

  return canvas;
}

function animate() {
  requestAnimationFrame(animate);

  const time = Date.now() / 6000;
  for (let i = 0, l = scene.children.length; i < l; i++) {
    const mesh = scene.children[i];
    mesh.position.x = Math.sin(time * 4) * i * i * 0.005;
    mesh.position.z = Math.cos(time * 6) * i * i * 0.005;
  }

  renderer.render(scene, camera);
}
